---
title: Initializing state on render
description: How to initialize atom state on initial render
nav: 7.13
---

There are times when you need to create an reusable component which uses atoms.

These atoms' initial state are determined by the props passed to the component.

Below is a basic example illustrating how you can use `Provider` and its prop, `initialValues`, to initialize state.

### Basic Example

> CodeSandbox link: [codesandbox](https://codesandbox.io/s/init-atoms-with-usehydrateatoms-nryk1w).

Consider a basic example where you have a reusable `TextDisplay` component that allows you to display and update plain text.

This component has two child components, `PrettyText` and `UpdateTextInput`.

- `PrettyText` displays the text in blue.
- `UpdateTextInput` is an input field which updates the text value.

As opposed to passing `text` as a prop in the two child components, you decided that the `text` state should be shared between components as an atom.

To make `TextDisplay` component reusable, we take in a prop `initialTextValue`, which determines the initial state of the `text` atom.

To tie `initialTextValue` to `textAtom`, we wrap the child components in a component where we create a new store and pass it to a `Provider` component.

```jsx
const textAtom = atom('')

const PrettyText = () => {
  const [text] = useAtom(textAtom)
  return (
    <>
      <text
        style={{
          color: 'blue',
        }}
      >
        {text}
      </text>
    </>
  )
}

const UpdateTextInput = () => {
  const [text, setText] = useAtom(textAtom)
  const handleInputChange = (e) => {
    setText(e.target.value)
  }
  return (
    <>
      <input onChange={handleInputChange} value={text} />
    </>
  )
}

const HydrateAtoms = ({ initialValues, children }) => {
  // initialising on state with prop on render here
  useHydrateAtoms(initialValues)
  return children
}

export const TextDisplay = ({ initialTextValue }) => (
  <Provider>
    <HydrateAtoms initialValues={[[textAtom, initialTextValue]]}>
      <PrettyText />
      <br />
      <UpdateTextInput />
    </HydrateAtoms>
  </Provider>
)
```

Now, we can easily reuse `TextDisplay` component with different initial text values despite them referencing the "same" atom.

```jsx
export default function App() {
  return (
    <div className="App">
      <TextDisplay initialTextValue="initial text value 1" />

      <TextDisplay initialTextValue="initial text value 2" />
    </div>
  )
}
```

This behavior is due to our child components looking for the lowest commmon `Provider` ancestor to derive its value.

For more information on `Provider` behavior, please read the docs [here](../core/provider.mdx).

For more complex use cases, check out [Scope extension](../extensions/scope.mdx).

### Using Typescript

`useHydrateAtoms` has overloaded types and typescript cannot extract types from overloaded function. It is recommended to use a `Map` when passing initial atom values to the `useHydrateAtoms`.

Here is a working example:

```tsx
import type { ReactNode } from 'react'
import { Provider, atom, useAtomValue } from 'jotai'
import type { WritableAtom } from 'jotai'
import { useHydrateAtoms } from 'jotai/utils'

const testAtom = atom('')

export default function App() {
  return (
    <Provider>
      <AtomsHydrator atomValues={[[testAtom, 'hello']]}>
        <Component />
      </AtomsHydrator>
    </Provider>
  )
}

//This component contains all the states and the logic
function Component() {
  const testAtomValue = useAtomValue(testAtom)
  return <div>{testAtomValue}</div>
}

function AtomsHydrator({
  atomValues,
  children,
}: {
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  atomValues: Iterable<
    readonly [WritableAtom<unknown, [any], unknown>, unknown]
  >
  children: ReactNode
}) {
  useHydrateAtoms(new Map(atomValues))
  return children
}
```
